Imports Col = System.Collections
Imports Gen = System.Collections.Generic
Imports Ref = System.Reflection
Imports Sys = System

Namespace Enhancements.Core.Logging
    ''' <summary>Represents a log processor, consisting of level mappings that define when to log, and writers that define where to log.</summary>
    <Serializable()> _
    Public NotInheritable Class Log

        ''' <summary>Initializes a Log instance.</summary>
        Public Sub New()
        End Sub

        Private __LevelMappingsCollection As LevelMappingCollection = New LevelMappingCollection(New LevelMappingGlobal(Level.Off, False))
        ''' <summary>Gets the level mappings.</summary>
        Public ReadOnly Property LevelMappings() As LevelMappingCollection
            Get
                ___Assert.___IsDisposedNot("Log[instance]", Me.___DisposeCalled, True)

                Return __LevelMappingsCollection
            End Get
        End Property

        Private __WritersCollection As WriterCollection = New WriterCollection()
        ''' <summary>Gets the writers.</summary>
        Public ReadOnly Property Writers() As WriterCollection
            Get
                ___Assert.___IsDisposedNot("Log[instance]", Me.___DisposeCalled, True)

                Return __WritersCollection
            End Get
        End Property

        Private __Use As Boolean = False
        ''' <summary>Gets and sets whether this instance is in effective processing.</summary>
        Public Property Use() As System.Boolean
            Get
                ___Assert.___IsDisposedNot("Log[instance]", Me.___DisposeCalled, True)

                Return __Use
            End Get
            Set(ByVal _value As System.Boolean)
                ___Assert.___IsDisposedNot("Log[instance]", Me.___DisposeCalled, True)

                __Use = _value
            End Set
        End Property

        Friend Sub ___Write(ByVal _record As ___Record)
            Try
                ___Assert.___IsDisposedNot("Log[instance]", Me.___DisposeCalled, True)
                ___Assert.___IsNullNot("_record", _record, True)

                ___Assert.___IsEmptyNot("_record.___UnformattedIdentifier", _record.___UnformattedIdentifier, True)
                ___Assert.___IsNullNot("_record.___UnformattedCallingProcedure", _record.___UnformattedCallingProcedure, True)
                ___Assert.___IsNullNot("_record.___UnformattedObjects", _record.___UnformattedObjects, True)

                If ___Assert.___IsTrue("Use", Use, False) Then
                    Dim _levelMappingsCollectionLevel As Level = Level.Off
                    Dim _levelMappingsCollectionLevelSearchContinue As System.Boolean = True
                    Dim _levelMappingGlobal As LevelMappingGlobal = LevelMappings.Global
                    Dim _levelMappingAssembly As LevelMappingAssembly = LevelMappings(_record.___UnformattedCallingProcedure.DeclaringType.Assembly)
                    Dim _levelMappingType As LevelMappingType = LevelMappings(_record.___UnformattedCallingProcedure.DeclaringType)

                    _levelMappingsCollectionLevel = _levelMappingGlobal.Level
                    If ___Assert.___IsTrue("LevelMappings.Global.OverridesDescendants", _levelMappingGlobal.OverridesDescendants, False) Then
                        _levelMappingsCollectionLevelSearchContinue = False
                    End If

                    If ___Assert.___IsTrue("_levelMappingsCollectionLevelSearchContinue", _levelMappingsCollectionLevelSearchContinue, False) Then
                        If ___Assert.___IsNullNot("_levelMappingAssembly", _levelMappingAssembly, False) Then
                            _levelMappingsCollectionLevel = _levelMappingAssembly.Level
                            If ___Assert.___IsTrue("_levelMappingAssembly.OverridesDescendants", _levelMappingAssembly.OverridesDescendants, False) Then
                                _levelMappingsCollectionLevelSearchContinue = False
                            End If
                        End If
                    End If

                    If ___Assert.___IsTrue("_levelMappingsCollectionLevelSearchContinue", _levelMappingsCollectionLevelSearchContinue, False) Then
                        If ___Assert.___IsNullNot("_levelMappingType", _levelMappingType, False) Then
                            _levelMappingsCollectionLevel = _levelMappingType.Level
                            If ___Assert.___IsTrue("_levelMappingType.OverridesDescendants", _levelMappingType.OverridesDescendants, False) Then
                                _levelMappingsCollectionLevelSearchContinue = False
                            End If
                        End If
                    End If

                    If _record.___UnformattedLevel <= _levelMappingsCollectionLevel AndAlso _record.___UnformattedLevel <> Level.Off Then
                        __WritersCollection.___Write(_record)
                    End If
                End If

            Catch _exception As Exception
                Logs.___OnExceptionOccurred(_exception)

            End Try
        End Sub

        Private __DisposeCalled As System.Boolean = False
        Friend Property ___DisposeCalled() As System.Boolean
            Get
                Return __DisposeCalled
            End Get
            Private Set(ByVal _value As System.Boolean)
                ___Assert.___IsDisposedNot("Log[instance]", ___DisposeCalled, True)
                ___Assert.___IsTrue("___DisposeCalled._value", _value, True)

                __DisposeCalled = _value
            End Set
        End Property
        Friend Sub ___Dispose()
            ___Assert.___IsDisposedNot("Log[instance]", ___DisposeCalled, True)
            ___DisposeCalled = True

            __LevelMappingsCollection.___Dispose()
            __WritersCollection.___Dispose()
        End Sub

    End Class
End Namespace
